#ifndef GAME_H
#define GAME_H

#include <ncurses.h>
#include <string>
#include <vector>
#include <memory>

#include "snake.h"


class Game
{
public:
    Game();
    Game(int skinIndex);  // 添加带皮肤索引的构造函数
    ~Game();
    
		void createInformationBoard();
    void renderInformationBoard() const;

    void createGameBoard();
    void renderGameBoard() const;
    
		void createInstructionBoard();
    void renderInstructionBoard() const;
		
		void loadLeadBoard();
    void updateLeadBoard();
    bool readLeaderBoard();
    bool updateLeaderBoard();
    bool writeLeaderBoard();
    void renderLeaderBoard() const;
    
		void renderBoards() const;
    
		void initializeGame();
    void runGame();
    void renderPoints() const;
    void renderDifficulty() const;    void createRamdonFood();
    void renderFood() const;
    void renderSnake() const;
    bool controlSnake() ;
    void renderObstacles() const;
    
		void startGame();
    bool renderRestartMenu() const;
    void adjustDelay();
    
    // 暂停相关方法
    void togglePause();
    void renderPauseMenu() const;
    bool isPaused() const;
    
    // 皮肤相关方法
    void setSkinSymbol(int skinIndex);
    char getSkinSymbol(int skinIndex) const;

private:
    // We need to have two windows
    // One is for game introduction
    // One is for game mWindows
    int mScreenWidth;
    int mScreenHeight;
    int mGameBoardWidth;
    int mGameBoardHeight;
    const int mInformationHeight = 6;
    const int mInstructionWidth = 18;
    std::vector<WINDOW *> mWindows;
    // Snake information
    const int mInitialSnakeLength = 2;
    const char mSnakeSymbol = '@';
    char mCurrentSnakeSymbol;  // 当前使用的蛇身符号
    int mCurrentSkinIndex = 0;  // 当前皮肤索引
    std::unique_ptr<Snake> mPtrSnake;
    // Food information
    SnakeBody mFood;
    const char mFoodSymbol = '#';
    int mPoints = 0;
    int mDifficulty = 0;
    int mBaseDelay = 100;
    int mDelay;
    const std::string mRecordBoardFilePath = "record.dat";
    std::vector<int> mLeaderBoard;
    const int mNumLeaders = 3;
    int mBonusPoints = 0;
    const int mBonusScore = 2;
    const float mBonusProbability = 0.3f;

    std::vector<SnakeBody> mObstacles;//新增mObstacles 用于存储障碍物
    void createReadomObstacles(); //新增createReadomObstacles 用于创建随机障碍物
    bool isFoodReachable() const; //新增isFoodReachable 用于检查食物是否可达
    bool mObstacleBypass = false; //新增mObstacleBypass 用于控制是否穿过障碍物
    long long mFrameCounter = 0;              // 游戏总帧数计数器
    long long mLastBypassKeyPressFrame = -1;  // 最后一次按J键的帧数，-1代表无效
    const int mBypassInputWindow = 3;         // 定义3帧的时间窗口
    
    // 暂停相关成员变量
    bool mIsPaused = false;
};

#endif
